/*
 * CMediaPlayer.h
 *
 *  Created on: 2015年6月1日
 *      Author: chuanjiang.zh@qq.com
 */

#ifndef CMEDIAPLAYER_H_
#define CMEDIAPLAYER_H_

#include "MediaPlayer.h"
#include "Ffmpeg.h"
#include "TCriticalSection.h"
#include "SDL.h"
#include "AVFrameQueue.h"
#include "HwndPresenter.h"
#include "TThread.h"
#include "TEvent.h"
#include "AVPacketQueue.h"


class CMediaPlayer: public MediaPlayer, public comn::Thread
{
public:
    CMediaPlayer();
    virtual ~CMediaPlayer();

    virtual int open(int vcodec, int acodec, int samplerate, int channels);

    virtual void close();

    virtual bool isOpen();

    virtual void setVideoWnd(HWND hwnd);

    virtual int input(const MediaPacket& pkt);

protected:
    virtual int run();
    virtual void doStop();

    void handle(AVPacketPtr& pkt);

protected:

    int openVideoCodec(AVCodecID id);
    void closeVideoCodec();

    void inputVideo(AVPacket& pkt);
    void renderVideo(AVFrame* frame);

    int openAudioCodec(AVCodecID id);
    void closeAudioCodec();
    void inputAudio(AVPacket& pkt);
    void renderAudio(AVFrame* frame);


    bool openAudioDev();
    void closeAudioDev();
    bool isAudioDevOpen();
    static void sdlAudioCallback(void* userdata, Uint8* stream, int len);
    void audioCallback(Uint8* stream, int len);

    int mixFrame(AVFrame* pFrame, Uint8* buffer, int size, int vol, bool& consumed);
    int mixFrame(AVFrame* pFrame, int pos, Uint8* buffer, int size, int vol, bool& consumed);
    int mixLastFrame(Uint8* buffer, int size, int vol);

    void saveFrame(AVFrame* pFrame, int pos);
    void clearFrame();

    int resample(AVFrame* inFrame, AVFrame* outFrame);

protected:
    AVCodecContext* m_videoCodecCtx;
    AVCodecParserContext*   m_parserCtx;
    AVCodecID m_videoCodecID;

    AVCodecContext* m_audioCodecCtx;
    AVCodecID m_audioCodecID;
    int m_channels;
    int m_sampleRate;

    HWND    m_hwnd;
    HwndPresenter   m_render;

    comn::CriticalSection   m_cs;

    SDL_AudioDeviceID   m_audioDev;
    SDL_AudioSpec       m_audioSpec;
    AVFrame*    m_curFrame;
    int         m_framePos;
    AVFrameQueue m_frameQueue;

    int     m_state;
    comn::Event m_event;
    AVPacketQueue   m_pktQueue;

    int m_videoPktCount;
    int m_audioPktCount;
    //std::string m_osd;

    SwrContext*		m_swrContext;

};


#endif /* CMEDIAPLAYER_H_ */
